/******************************************************************************
 * Copyright 2013-2014 Espressif Systems (Wuxi)
 *
 * FileName: user_main.c
 *
 * Description: entry file of user application
 *
 * Modification history:
 *     2014/1/1, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
//#include "osapi.h"
#include "uart.h"
#include "gpio.h"
//#include "user_interface.h"
#include "smartlink.h"
#include "SysLayerInit.h"
#include "zc_hf_adpter.h"
#include "esp_wifi.h"
#include "esp_misc.h"

#include "esp_common.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "c_types.h"
#include "smartconfig.h"

volatile unsigned long  g_ulStatus = 0;
xTaskHandle key_handler_task_handle;
extern u32 Update_Flash_addr;
extern int ESP_Init(void);

void uart0_send_str(uint8 *str)
{
	uint16 size = 0;
	uint8 string[40] = {"\0"};
	uint8 *str1 = str;

	while(*str1!='\0')
	{
		str1++;
		size++;
	}

	sprintf(string,"size=%d\r\n",size);
	uart0_tx_buffer(string,sizeof(string));

	uart0_tx_buffer((uint8*)str, size);
}

void ICACHE_FLASH_ATTR
smartconfig_done(sc_status status, void *pdata)
{
    switch(status) {
        case SC_STATUS_WAIT:
            printf("SC_STATUS_WAIT\n");
            break;
        case SC_STATUS_FIND_CHANNEL:
            printf("SC_STATUS_FIND_CHANNEL\n");
            break;
        case SC_STATUS_GETTING_SSID_PSWD:
            printf("SC_STATUS_GETTING_SSID_PSWD\n");
            sc_type *type = pdata;
            if (*type == SC_TYPE_ESPTOUCH) {
                printf("SC_TYPE:SC_TYPE_ESPTOUCH\n");
            } else {
                printf("SC_TYPE:SC_TYPE_AIRKISS\n");
            }
            break;
        case SC_STATUS_LINK:
            printf("SC_STATUS_LINK\n");
            struct station_config *sta_conf = pdata;

	        wifi_station_set_config(sta_conf);
	        wifi_station_disconnect();
	        wifi_station_connect();
            break;
        case SC_STATUS_LINK_OVER:
            printf("SC_STATUS_LINK_OVER\n");
            if (pdata != NULL) {
				//SC_TYPE_ESPTOUCH
                uint8 phone_ip[4] = {0};

                memcpy(phone_ip, (uint8*)pdata, 4);
                printf("Phone ip: %d.%d.%d.%d\n",phone_ip[0],phone_ip[1],phone_ip[2],phone_ip[3]);
            } else {
            	//SC_TYPE_AIRKISS - support airkiss v2.0
				//airkiss_start_discover();
			}
            smartconfig_stop();
            break;
    }
}

/*************************************************
* Function: wifi_handle_event_cb
* Description: 
* Author: cxy 
* Returns: 
* Parameter: 
* History:
*************************************************/
void wifi_handle_event_cb(System_Event_t *evt) 
{  
    u32 free_size = system_get_free_heap_size();
    //os_printf ("free heap size is %d\n",free_size);
    //os_printf("event %x\n", evt->event_id);
    //system_print_meminfo();
    switch (evt->event_id) 
    {      
        case EVENT_STAMODE_CONNECTED:
            os_printf("connect to ssid %s, channel %d\n", 
                                evt->event_info.connected.ssid, 
                                evt->event_info.connected.channel);
            CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_DISCONNECTED);
            SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
            break;      
        case EVENT_STAMODE_DISCONNECTED:
            os_printf("disconnect from ssid %s, reason %d\n",
                                evt->event_info.disconnected.ssid,
                                evt->event_info.disconnected.reason);
            SET_STATUS_BIT(g_ulStatus, STATUS_BIT_DISCONNECTED);
            CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
            CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_AQUIRED);
            break;      
        case EVENT_STAMODE_AUTHMODE_CHANGE:
            os_printf("mode: %d -> %d\n",
                            evt->event_info.auth_change.old_mode,
                            evt->event_info.auth_change.new_mode);
            break;      
        case EVENT_STAMODE_GOT_IP:
            CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_DISCONNECTED);
            SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_AQUIRED);
            break;
        case EVENT_SOFTAPMODE_STACONNECTED:          
            printf("station: " MACSTR "join, AID = %d\n",      
                    MAC2STR(evt->event_info.sta_connected.mac), 
                    evt->event_info.sta_connected.aid); 
            CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_DISCONNECTED);
            SET_STATUS_BIT(g_ulStatus, STATUS_BIT_AP_CONNECTION);
            break; 
        case EVENT_SOFTAPMODE_STADISCONNECTED:
            printf("station: " MACSTR "leave, AID = %d\n",
                    MAC2STR(evt->event_info.sta_disconnected.mac),      
                    evt->event_info.sta_disconnected.aid);  
            SET_STATUS_BIT(g_ulStatus, STATUS_BIT_DISCONNECTED);
            CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
            CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_AQUIRED);
            CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_AP_CONNECTION);
            break;
        default:
            break;
    } 
} 
/*************************************************
* Function: user_pre_init
* Description: 
* Author: cxy 
* Returns: 
* Parameter: 
* History:
*************************************************/
void //ICACHE_FLASH_ATTR 
user_pre_init(void)
{
	Sys_LayerInit();//ÉèÖÃÏµÍ³µÎ´ðÊ±ÖÓ
    ESP_Init();//esp³õÊ¼»¯
}

/*************************************************
* Function: led_init
* Description:
* Author: cxy
* Returns:
* Parameter:
* History:
*************************************************/
void led_init(void)
{
	 GPIO_ConfigTypeDef GPIOConfig;
	 GPIOConfig.GPIO_Pin =  (BIT(4)) ;
	 GPIOConfig.GPIO_Pullup = GPIO_PullUp_EN;
	 GPIOConfig.GPIO_Mode = GPIO_Mode_Output;
	 GPIOConfig.GPIO_IntrType = GPIO_PIN_INTR_DISABLE;
	 gpio_config(&GPIOConfig);
}

/*************************************************
* Function: led_toggle_task
* Description:
* Author: cxy
* Returns:
* Parameter:
* History:
*************************************************/
void ICACHE_FLASH_ATTR
led_toggle_task(void *pvParameters)
{
	led_init();
	os_printf("Hello, welcome to led_toggle_task!\r\n");
	while (1)
	{
#if 0
		GPIO_OUTPUT( (BIT(4)) ,0);
		os_printf("led_toggle on!\r\n");
		vTaskDelay(500/portTICK_RATE_MS);
		GPIO_OUTPUT( (BIT(4)) ,1);
		os_printf("led_toggle off!\r\n");
		vTaskDelay(500/portTICK_RATE_MS);
#endif
	}
	vTaskDelete(NULL);
}

void key_int_handler(void)
{
	uint32_t gpio_status;

	gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
	GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS,gpio_status);

	if(gpio_status&(BIT(5)))
	{
		//os_printf("press key!!!\r\n");
		xTaskResumeFromISR(key_handler_task_handle);
	}
}

void key_init(void)
{
	GPIO_ConfigTypeDef GPIOConfig;

	GPIOConfig.GPIO_Pin = (BIT(5)) ;
	GPIOConfig.GPIO_IntrType = GPIO_PIN_INTR_NEGEDGE;
	GPIOConfig.GPIO_Mode = GPIO_Mode_Input;
	GPIOConfig.GPIO_Pullup = GPIO_PullUp_DIS;
	gpio_config(&GPIOConfig);

	gpio_intr_handler_register(key_int_handler, NULL);
	_xt_isr_unmask(1 << 4);
}

void ICACHE_FLASH_ATTR
key_handler_task(void *pvParameters)
{
	uint32_t TickCountPre = 0, TickCountCur = 0;
	static uint8_t led_status = 0;
	key_init();
	for( ; ; )
	{
		vTaskSuspend(NULL);
		TickCountPre = TickCountCur;
		TickCountCur = xTaskGetTickCount();
		os_printf("TickCountPre:%d-----TickCountCur:%d-----chazhi:%d\r\n", TickCountPre, TickCountCur, TickCountCur - TickCountPre);
		if(TickCountCur - TickCountPre> 8)
		{
			os_printf("read press\r\n");
			uint8_t i;
			for(i=0; i<200; i++)
			{
				vTaskDelay(10/portTICK_RATE_MS);
				uint32_t gpio_value;
				gpio_value = gpio_input_get();
				if((gpio_value&BIT(5)) == BIT(5))
				{
					os_printf("break:%d\r\n",i);
					break;
				}
			}
			if((3 <= i)&&(i <= 100))
			{
				if(led_status == 0)
				{
					led_status = 1;
					GPIO_OUTPUT( (BIT(4)) ,0);
					os_printf("led_toggle on!\r\n");
				}
				else if(led_status == 1)
				{
					led_status = 0;
					GPIO_OUTPUT( (BIT(4)) ,1);
					os_printf("led_toggle off!\r\n");
				}
			}
			if(i >= 100)
			{
				os_printf("press key 1 second!\r\n");
				AC_SendRestMsg();
				//SmartLinkInter();
				//smartconfig_start(smartconfig_done);
			}
		}
	}
}

/*************************************************
* Function: user_init
* Description: 
* Author: cxy 
* Returns: 
* Parameter: 
* History:
*************************************************/
void user_init(void)
{
    UartInit();//´®¿Ú³õÊ¼»¯½ÓÊÕ»º´æ
	uart_init_new();//´®¿Ú³õÊ¼»¯ÅäÖÃ²ÎÊý
	os_printf("\r\n%s from 0x%x \r\n", SYS_VERSION, system_get_userbin_addr());
    os_delay_us(100);
    wifi_set_event_handler_cb(wifi_handle_event_cb);
    //espconn_init();
    wifi_set_opmode(STATION_MODE);//stationÄ£Ê½
    //SmartLinkInter();//¿ªÊ¼smartconfig
    user_pre_init();

    os_printf("\r\nshenzhen hashest Technology co.,Ltd\r\n");

    xTaskCreate(led_toggle_task, "led_toggle_task", 256, NULL, 2, NULL);
    xTaskCreate(key_handler_task,"key_handler_task",256,NULL,3,&key_handler_task_handle);
}
